﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Diagnostics;
using WeifenLuo.WinFormsUI.Docking;
using KrisThom;
using KrisThom.Execute;
using KrisThom.Email;

namespace Mole
{
    public partial class FrmSiteScan : DockContent
    {

        private UrlSession _session;
        private BindingSource _url = new BindingSource();
        public DockPanel _dockPanelMain;
        public DataGridViewRow _openRow;
        
        public FrmSiteScan(UrlSession session)
        {
            InitializeComponent();

            _session = session;

            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.DataSource = _session.UrlComplete;
            dataGridView1.AutoSize = true;

            dataGridView2.AutoGenerateColumns = true;
            dataGridView2.DataSource = _session.DirectoryListUrl;

            //progress bar
            this.pbStatus.Minimum = 0;
            this.pbStatus.Maximum = _session.UrlTargets.Count();
            this.pbStatus.Step = 1;
            this.Enabled = true;

            this.Text = _session.ProjectName;
        }

        public void StartScan()
        {

            if (_session.UrlTargets != null)
            {
                if (!bwTracking.IsBusy)
                {
                    bwTracking.RunWorkerAsync(_session.UrlTargets);
                }

            }
        }

        #region backgroundworker

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            List<String> urlTargets = (List<String>)e.Argument;
            //UrlProcessed urlDone;
            String fullurlDir = String.Empty;

            if (urlTargets != null)
            {

                //Create Today's Directory
                String todayDir = String.Format("{0}\\{1}", _session.AppDir, _session.ProjectName);
               if (!System.IO.Directory.Exists(todayDir))
                {
                    System.IO.Directory.CreateDirectory(todayDir);
                }

                foreach (String sUrl in urlTargets)
                {
                   
                    try
                    {
                        _session.SiteId++;

                        UrlProcessing process = new UrlProcessing(_session.ProjectName, sUrl, _session.SiteId);
                        process.Start();
                        bwTracking.ReportProgress(0, process);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                }
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //load first record
            try
            {
                uint select = (uint)dataGridView1.Rows[0].Cells["SiteID"].Value;
                LoadGridViewFiles(select);
            }
            catch { }
            MessageBox.Show("Scan Complete");
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            UrlProcessing urlDone = e.UserState as UrlProcessing;
            _session.UrlComplete.Add(urlDone.UrlProcessed);

            foreach (DirectoryList file in urlDone.FilesProcessed)
            {
                _session.DirectoryListAll.Add(file);
            }

            //update progress
            pbStatus.PerformStep();
        }

        #endregion

        #region datagridview
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            //get directory
            try
            {
                if (e.RowIndex >= 0)
                {
                    uint select = (uint)dataGridView1.Rows[e.RowIndex].Cells["SiteID"].Value;
                    LoadGridViewFiles(select);
                }
            }
            catch { }
            
         }

        private void LoadGridViewFiles(uint siteid)
        {
            //_DirectoryListUrl
            _session.DirectoryListUrl.Clear();
            foreach (DirectoryList dirlist in _session.DirectoryListAll)
            {
                if (dirlist.SiteId == siteid)
                {
                    _session.DirectoryListUrl.Add(dirlist);
                }
            }
        }

        private void LoadGridViewFiles(String[] extensions)
        {
            _session.DirectoryListUrl.Clear();
            foreach (DirectoryList dirlist in _session.DirectoryListAll)
            {
                foreach (String s in extensions)
                {
                    if (String.Equals(dirlist.FileExt, s, StringComparison.OrdinalIgnoreCase))
                    {
                        _session.DirectoryListUrl.Add(dirlist);
                    }
                }
            }
        }

        private void LoadGridViewFiles()
        {
            _session.DirectoryListUrl.Clear();
            foreach (DirectoryList dirlist in _session.DirectoryListAll)
            {
                _session.DirectoryListUrl.Add(dirlist);
            }
        }

        private void LoadGridViewFiles(String filetype)
        {
            _session.DirectoryListUrl.Clear();
            foreach (DirectoryList dirlist in _session.DirectoryListAll)
            {
                 if (FileConfig.isMatch(dirlist.FileExt,filetype,dirlist.FileType))
                {
                    _session.DirectoryListUrl.Add(dirlist);
                }
            }
        }

        private String GetGridViewCell(String cellname)
        {
            String value = String.Empty;

            try
            {
                value = dataGridView1.SelectedRows[0].Cells[cellname].Value.ToString();
            }
            catch { }

            return value;
        }


        #endregion

        #region GetFilePaths
        private String[] GetFilePaths(String[] extensions)
        {
            List<String> value = new List<string>();
            foreach (DirectoryList list in _session.DirectoryListAll)
            {
                foreach (String ext in extensions)
                {
                    if (String.Equals(ext, list.FileExt, StringComparison.OrdinalIgnoreCase))
                    {
                        value.Add(list.FilePath);
                    }
                }
            }

            return value.ToArray();
        }

        private String[] GetFilePaths(String filetype)
        {
            List<String> value = new List<string>();
            foreach (DirectoryList dirlist in _session.DirectoryListAll)
            {
                if (FileConfig.isMatch(dirlist.FileExt,filetype, dirlist.FileType))
                {
                    value.Add(dirlist.FilePath);
                }
            }

            return value.ToArray();
        }

        private List<DirectoryList> GetFilePaths(String filetype, BindingList<DirectoryList> list)
        {
            List<DirectoryList> DirList = new List<DirectoryList>();

            foreach (DirectoryList dirlist in list)
            {
                if (FileConfig.isMatch(dirlist.FileExt, filetype, dirlist.FileType))
                {
                    DirList.Add(dirlist);
                }
            }

            return DirList;
        }
        #endregion

        #region toolstripbuttons
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("Are you sure you really want to do this? You might get pwnd!","Open Web browser",MessageBoxButtons.OKCancel,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button2);
            if (dr == DialogResult.OK)
            {

                Process proc = new Process();
                proc.StartInfo.FileName = "iexplore";
                proc.StartInfo.Arguments = GetGridViewCell("Url");
                proc.Start();
            }
            
        }

        private void filesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadGridViewFiles();
        }

        private void picturesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadGridViewFiles("IMAGE");
            //LoadGridViewFiles(new String[] { ".jpg", ".gif", ".png", ".bmp", ".tiff" });
        }

        private void executablesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadGridViewFiles("EXECUTABLE");
            //LoadGridViewFiles(new String[] { ".exe", ".com", ".cmd", ".bat", ".msi", ".scr" });
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            LoadGridViewFiles("COMPRESSED");
            //LoadGridViewFiles(new String[] { ".zip", ".rar", ".lzh", ".cab" });
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            Process.Start(GetGridViewCell("Directory"));
        }

        private void picturesViewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmPicturesView frm = new FrmPicturesView();

            //Copy file path to pictures
            //frm._filepath = GetFilePaths("IMAGE");
            frm._dirlist = GetFilePaths("IMAGE", _session.DirectoryListAll);
            // frm._filepath = GetFilePaths(new string[] { ".jpg", ".gif", ".png", ".bmp", ".tiff" });
            frm._dockPanelMain = _dockPanelMain;
            frm.Show(_dockPanelMain);

            frm.LoadPictureList(0);
        }

        private void virusTotalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            //Get API Key
            String VTApiKey = Properties.Settings.Default.AV_VirusTotal_API;

            if (String.IsNullOrEmpty(VTApiKey))
            {
                MessageBox.Show("VirusTotal API Key not found, please enter it under Settings", "API key missing", MessageBoxButtons.OK);
                return;
            }

            this.Cursor = Cursors.WaitCursor;
            

            LoadGridViewFiles("EXECUTABLE");

            foreach (DirectoryList dirlist in _session.DirectoryListUrl)
            {
                try
                {
                    VirusTotalResults vtr = new VirusTotalResults();

                    //Check for MD5 hash first if not successfull upload the file itself
                    vtr = VirusTotalScan.MD5(VTApiKey, dirlist.FileHashMD5);

                    if (vtr.ResultStatus == VirusTotalResults.Status.Success)
                    {
                        dirlist.Malware = vtr.MalwareFound;
                        dirlist.MalwareDetectedBy += "VirusTotal";
                        dirlist.MalwareName += String.Format("(MD5 Match) - {1}% \t{0}", vtr.PermaLink, vtr.MalwarePercent.ToString());
                    }
                    else
                    {
                        vtr = VirusTotalScan.Upload(VTApiKey, new FileInfo(dirlist.FilePath));
                        if (vtr.ResultStatus == VirusTotalResults.Status.Success)
                        {
                            dirlist.Malware = false;
                            dirlist.MalwareDetectedBy += "VirusTotal";
                            dirlist.MalwareName += String.Format("(Uploaded) - {0}", vtr.PermaLink);
                        }
                    }


                    if (vtr.ResultStatus != VirusTotalResults.Status.Success)
                    {
                        dirlist.Malware = false;
                        dirlist.MalwareDetectedBy += "VirusTotal";
                        dirlist.MalwareName += String.Format("VirusTotal Warning: [{0}]", Enum.GetName(typeof(VirusTotalResults),vtr.ResultStatus));
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            this.Cursor = Cursors.Default;
            MessageBox.Show("VirusTotal Complete");
        }

        private void antiGenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            String[] ToField = new String[] { Properties.Settings.Default.AV_VirusTotal_TO };
            String FromField = Properties.Settings.Default.AV_Antigen_FROM;
            String Server = Properties.Settings.Default.SMTP_RELAY_SERVER;
            String SMTPUser = Properties.Settings.Default.SMTP_USER;
            String SMTPPass = Properties.Settings.Default.SMTP_PASS;

            String[] FileAry = GetFilePaths("EXECUTABLE");

            foreach (String file in FileAry)
            {
                try
                {
                    FileInfo fileinfo = new FileInfo(file);

                    Send.CreateMessageWithAttachment(Server, SMTPUser, SMTPPass, ToField, FromField, "SCAN", file, new string[] { file });
                }
                catch { }
            }

            MessageBox.Show("AntiGen Complete");
        }

  
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_openRow != null)
            {
                String filename = "";
                try
                {
                    filename = Properties.Settings.Default.FILEOPEN;
                }
                catch
                {
                    filename = "write.exe";
                }


                try
                {
                    String FilePath = "\"" + _openRow.Cells["FilePath"].Value.ToString() + "\"";

                    //open file
                    //ProcessStartInfo startInfo = new ProcessStartInfo();
                    //startInfo.FileName = filename;
                    //startInfo.Arguments = filepath;
                    //startInfo.RedirectStandardOutput = false;
                    //startInfo.WindowStyle = ProcessWindowStyle.Normal;
                    //startInfo.CreateNoWindow = false;
                    //startInfo.UseShellExecute = false;
                    //startInfo.ErrorDialog = false;

                    //Process processRun = new Process();
                    //processRun.StartInfo = startInfo;
                    //processRun.Start();

                    Execute execute = new Execute();
                    execute.Run(filename, FilePath, WindowStyle.Normal);

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void dataGridView2_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (e.RowIndex >= 0)
                {
                    dataGridView2.Rows[e.RowIndex].Selected = true;
                    _openRow = dataGridView2.Rows[e.RowIndex];
                    dataGridView2.ContextMenuStrip.Show(this.dataGridView2, new Point(e.RowIndex, e.ColumnIndex));
                }
            }
        }

        private void topViewCSVToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
            saveFileDialog1.FileName = "URL.csv";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                    String data = "SiteID,URL,Directory,ScanTime\r\n";

                    foreach (UrlProcessed processed in _session.UrlComplete)
                    {
                        data += String.Format("{0},{1},{2},{3}\r\n", processed.SiteId.ToString(), processed.Url, processed.Directory,processed.ScanTime.ToString());
                    }

                    try
                    {
                        File.WriteAllText(saveFileDialog1.FileName,data);

                        Execute exe = new Execute();
                        exe.Run(saveFileDialog1.FileName, "", WindowStyle.Normal);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }

        private void bottomUrlOnlyTXTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            saveFileDialog1.FileName = "URL.txt";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                String data = "";

                foreach (DirectoryList dir in _session.DirectoryListUrl)
                {
                    data += String.Format("{0}\r\n", dir.SiteUrl);
                }

                try
                {
                    File.WriteAllText(saveFileDialog1.FileName, data);

                    Execute exe = new Execute();
                    exe.Run(saveFileDialog1.FileName, "", WindowStyle.Normal);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void bottomViewCSVToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
            saveFileDialog1.FileName = "URL.csv";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                String data = "SiteID,SiteURL,FilePath,FileName,FileExt,FileType,FileSize,FileHashMD5,ExtMismatch,BadCode,BadCodeDesc,Malware,MalwareDetectedBy,MalwareName\r\n";

                foreach (DirectoryList dir in _session.DirectoryListUrl)
                {
                    data += String.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11}\r\n", 
                        dir.SiteId.ToString().TrimEnd(),
                        dir.SiteUrl.TrimEnd(),
                        dir.FilePath.TrimEnd(),
                        dir.FileName.TrimEnd(),
                        dir.FileExt.TrimEnd(),
                        dir.FileType.Replace(',', ';').Trim(),
                        dir.FileSize.ToString().TrimEnd(),
                        dir.FileHashMD5.TrimEnd(), 
                        dir.ExtMismatch.ToString().TrimEnd(), 
                        dir.Malware.ToString().TrimEnd(),
                        dir.MalwareDetectedBy.TrimEnd(),
                        dir.MalwareName.TrimEnd()
                        );
                }

                try
                {
                    File.WriteAllText(saveFileDialog1.FileName, data);

                    Execute exe = new Execute();
                    exe.Run(saveFileDialog1.FileName, "", WindowStyle.Normal);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void aLLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            virusTotalToolStripMenuItem_Click(null, EventArgs.Empty);
        }

        private void executablesALLToolStripMenuItem_Click(object sender, EventArgs e)
        {

            try
            {
                using (SaveFileDialog DialogSave = new SaveFileDialog())
                {
                    DialogSave.DefaultExt = "zip";
                    DialogSave.Filter = "ZIP file (*.zip)|*.zip|All files (*.*)|*.*";
                    DialogSave.AddExtension = true;
                    DialogSave.RestoreDirectory = true;
                    DialogSave.Title = "Where do you want to save the file?";
                    DialogSave.InitialDirectory = @"C:/";

                    // Show the dialog and process the result
                    if (DialogSave.ShowDialog() == DialogResult.OK)
                    {

                        List<ZipInput> files = new List<ZipInput>();
                        foreach (DirectoryList dirlist in _session.DirectoryListAll)
                        {
                            if (FileConfig.isMatch(dirlist.FileExt, "EXECUTABLE", dirlist.FileType))
                            {
                                files.Add(new ZipInput(dirlist.FilePath, dirlist.MalwareName));
                            }
                        }

                        //create zip file
                        string zipPassword = Properties.Settings.Default.ZIP_Password;

                        if (files.Count > 0)
                        {
                            String error = String.Empty;

                            if (!string.IsNullOrEmpty(zipPassword))
                            {
                                error = ZipFiles.Create(files.ToArray(), DialogSave.FileName, zipPassword);
                                MessageBox.Show(String.Format("File Saved - password is \"{0}\"",zipPassword));
                            }
                            else
                            {
                                error = ZipFiles.Create(files.ToArray(), DialogSave.FileName,null);
                                MessageBox.Show(String.Format("File Saved", zipPassword));
                            }

                            //show any errors 
                            if (!string.IsNullOrEmpty(error))
                            {
                                MessageBox.Show(error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("No files found");
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void executablesMALWAREToolStripMenuItem_Click(object sender, EventArgs e)
        {

            try
            {
                using (SaveFileDialog DialogSave = new SaveFileDialog())
                {
                    DialogSave.DefaultExt = "zip";
                    DialogSave.Filter = "ZIP file (*.zip)|*.zip|All files (*.*)|*.*";
                    DialogSave.AddExtension = true;
                    DialogSave.RestoreDirectory = true;
                    DialogSave.Title = "Where do you want to save the file?";
                    DialogSave.InitialDirectory = @"C:/";

                    // Show the dialog and process the result
                    if (DialogSave.ShowDialog() == DialogResult.OK)
                    {

                        List<ZipInput> files = new List<ZipInput>();
                        foreach (DirectoryList dirlist in _session.DirectoryListAll)
                        {
                            if (FileConfig.isMatch(dirlist.FileExt, "EXECUTABLE", dirlist.FileType))
                            {
                                if (dirlist.Malware)
                                {
                                    files.Add(new ZipInput(dirlist.FilePath, dirlist.MalwareName));
                                }
                            }
                        }

                        //create zip file
                        string zipPassword = Properties.Settings.Default.ZIP_Password;

                        if (files.Count > 0)
                        {
                            String error = String.Empty;

                            if (!string.IsNullOrEmpty(zipPassword))
                            {
                                error = ZipFiles.Create(files.ToArray(), DialogSave.FileName, zipPassword);
                                MessageBox.Show(String.Format("File Saved - password is \"{0}\"", zipPassword));
                            }
                            else
                            {
                                error = ZipFiles.Create(files.ToArray(), DialogSave.FileName, null);
                                MessageBox.Show(String.Format("File Saved", zipPassword));
                            }

                            //show any errors 
                            if (!string.IsNullOrEmpty(error))
                            {
                                MessageBox.Show(error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("No files found");
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        private void tsmSaveSession_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog save = new SaveFileDialog();
                save.InitialDirectory = _session.AppDir;
                save.FileName = "MOLE-Session.xml";
                save.Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*";
                save.Title = "Save Session XML";

                if (save.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    _session.SaveXml(save.OpenFile());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("Error saving - {0}", ex.InnerException.Message),"Save",MessageBoxButtons.OK);
            }
        }

    } 
}
